package com.collabscm.pf.web;

import java.io.Serializable;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.ServletActionContext;

import com.collabscm.pf.auth.UserInfo;
import com.collabscm.pf.logging.Logger;
import com.collabscm.pf.logging.LoggerFactory;
import com.collabscm.pf.service.ApplicationService;
import com.collabscm.pf.util.BeanFactoryUtils;
import com.collabscm.pf.util.RuntimeContext;
import com.collabscm.pf.validation.BeanValidationFailure;
import com.collabscm.pf.validation.BeanValidationUtils;
import com.collabscm.pf.vo.QueryCondition;
import com.collabscm.pf.vo.QueryParameters;
import com.opensymphony.xwork2.Action;

/**
 * 基础Action，系统内所有Action的基类。
 * 
 * @author Zeng Raoxing
 */
public abstract class BaseAction implements Action, Serializable {
	private static final long serialVersionUID = 1L;
	/**
	 * 不事先初始化，目的是为了仅在使用时再创建Logger对象。
	 */
	private Logger logger;
	
	/**
	 * 得到Logger对象
	 */
	protected Logger getLogger() {
		if(logger == null) {
			logger = LoggerFactory.getLogger(getClass());
		}
		return logger;
	}

	/**
	 * 记录跟踪信息
	 * 
	 * @param format 待格式化数据
	 * @param args   格式化的参数
	 */
	protected void logTrace(String format, Object... args) {
		getLogger().trace(format, args);
	}

	/**
	 * 记录调试信息
	 * 
	 * @param format 待格式化数据
	 * @param args   格式化的参数
	 */
	protected void logDebug(String format, Object... args) {
		getLogger().debug(format, args);
	}

	/**
	 * 记录提示信息
	 * 
	 * @param format 待格式化数据
	 * @param args   格式化的参数
	 */
	protected void logInfo(String format, Object... args) {
		getLogger().info(format, args);
	}
	
	/**
	 * 记录警告信息
	 * 
	 * @param format 待格式化数据
	 * @param args   格式化的参数
	 */
	protected void logWarn(String format, Object... args) {
		getLogger().warn(format, args);
	}
	
	/**
	 * 记录异常信息
	 * 
	 * @param format 待格式化数据
	 * @param args   格式化的参数
	 */
	protected void logError(String format, Object... args) {
		getLogger().error(format, args);
	}

	/**
	 * 得到当前的HttServletRequest
	 */
	public HttpServletRequest getRequest() {
		return ServletActionContext.getRequest();
	}
	
	/**
	 * 得到当前的HttpServletResponse
	 */
	public HttpServletResponse getResponse() {
		return ServletActionContext.getResponse();
	}
	
	/**
	 * 得到当前的用户信息
	 */
	public UserInfo getUserInfo() {
		return RuntimeContext.getCurrentUserInfo();
	}
	
	/**
	 * 获得Service实例，防止每次创建Action实例时调用反射方法进行设置。
	 * 
	 * @param <T>       ApplicationService的实例
	 * @param beanClass 具体Service的Class类
	 */
	public <T extends ApplicationService> T getService(Class<T> beanClass) {
		return BeanFactoryUtils.getBean(beanClass);
	}
	
	/**
	 * 每个Action必须编写自己的execute方法，不允许直接使用execute方法，
	 * 即要求每个Action必须有处理多件事。
	 */
	@Override public final String execute() {
		return SUCCESS;
	}
	
	/**
	 * 验证对象
	 * 
	 * @param propertyName 待验证的属性名
	 * @param bean         待验证的属性对象
	 */
	public void validate(String propertyName, Object bean) {
		try {
			BeanValidationUtils.validate(bean);
		} catch (BeanValidationFailure failure) {
			//添加一个属性名，以便能正常的给页面提示
			failure.setRootBean(propertyName);
			throw failure;
		}
	}
	
	/**
	 * 生成查询参数
	 * 
	 * @param qc 查询条件
	 */
	public QueryParameters buildQueryParameters(QueryCondition qc) {
		qc.validate();//先验证参数是否符合要求
		return QueryParametersBuilder.getInstance().build(qc);
	}

}
